package ru.nagakhl.whirlpool;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.cassandra.thrift.ConsistencyLevel;

import ru.nagakhl.whirlpool.annotations.ColumnFamily;
import ru.nagakhl.whirlpool.exceptions.MappingException;


public class BasicMetadata implements Metadata {
	
	protected final String keyspace;

	protected final String columnFamily;
	
	protected boolean superColumn = false;
	
	protected Field id;

	protected final Set<Field> mappedFields;
	
	protected Logger log;
	
	protected ConsistencyLevel level;
	
	BasicMetadata(Class<?> target, ConsistencyLevel defaultLevel) throws MappingException {
		log = Logger.getLogger(getClass().getSimpleName() + " for -> " + target.getSimpleName());
		level = defaultLevel;
		ColumnFamily cf = target.getAnnotation(ColumnFamily.class);
		if (cf == null)
			throw new MappingException("Attempt to create mapping without proper ColumnFamily annotation");
		if (cf.keyspace() == null)
			throw new MappingException("Attempt to create mapping without declaring keyspace for class");
		if (cf.name() == null)
			throw new MappingException("Attempt to create mapping without declaring column family for class");
		keyspace = cf.keyspace();
		columnFamily = cf.name();
		Set<Field> fields = new HashSet<Field>();
		boolean idDetected = false;
		Field[] declared = target.getDeclaredFields();
		for (Field f : declared) {
			if (f.getType().isPrimitive()) {
				Integer i = 1;
				
			}
			Annotation[] markers = f.getAnnotations();
			if (markers.length != 0) {
				
			} else {
				
			}
		}
		mappedFields = Collections.unmodifiableSet(fields);
	}

//	protected void 
	
	/**
	 * {@inheritDoc}
	 */
	public String getKeyspace() {
		return keyspace;
	}

	/**
	 * {@inheritDoc}
	 */
	public String getColumnFamily() {
		return columnFamily;
	}

	/**
	 * {@inheritDoc}
	 */
	public String getId(Object obj) {
		try {
			return id.get(obj).toString();
		} catch (IllegalArgumentException e) {
			String message = "Attempt to get metadata from wrong type.";
			log.log(Level.SEVERE, message, e);
			throw new MappingException(message, e);
		} catch (IllegalAccessException e) {
			String message = "Error accessing id field value. Maybe security manager is turned on?";
			log.log(Level.SEVERE, message, e);
			throw new MappingException(message, e);
		}
	}
	
	/**
	 * {@inheritDoc}
	 */
	public ConsistencyLevel getLevel() {
		return level;
	}

	/**
	 * {@inheritDoc}
	 */
	public Map<byte[], byte[]> getFields(Object obj) {
		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean isSuperColumn() {
		return superColumn;
	}

	/**
	 * {@inheritDoc}
	 */
	public int fieldCount() {
		return mappedFields.size();
	}
	
	public Field getIdField() {
		return id;
	}

	public Set<Field> getPlainFields() {
		return mappedFields;
	}
}
